package edu.cmu.cs.stage3.alice.core.behavior;

import edu.cmu.cs.stage3.alice.core.Behavior;
import edu.cmu.cs.stage3.alice.core.Response;
import edu.cmu.cs.stage3.alice.core.Response.RuntimeResponse;
import edu.cmu.cs.stage3.alice.core.property.ObjectProperty;
import edu.cmu.cs.stage3.alice.core.property.ResponseProperty;

public class TriggerBehavior extends Behavior {

 public ResponseProperty triggerResponse = new ResponseProperty( this, "triggerResponse", null );
 public final ObjectProperty multipleRuntimeResponsePolicy = new ObjectProperty( this, "multipleRuntimeResponsePolicy", MultipleRuntimeResponsePolicy.ENQUEUE_MULTIPLE, MultipleRuntimeResponsePolicy.class );
 private java.util.Vector m_runtimeResponses = new java.util.Vector();
 private Response.RuntimeResponse[] m_runtimeResponseArray = null;
 private Response.RuntimeResponse[] getRuntimeResponseArray () {
  if (m_runtimeResponseArray == null) {
   m_runtimeResponseArray = new Response.RuntimeResponse[ m_runtimeResponses.size() ];
   m_runtimeResponses.copyInto( m_runtimeResponseArray );
   }
  return m_runtimeResponseArray;
  }

 public void trigger (double time) {
  //debugln( "trigger: " + time );
  if (m_runtimeResponses.size() > 0) {
   if (multipleRuntimeResponsePolicy.getValue()==MultipleRuntimeResponsePolicy.IGNORE_MULTIPLE) {
    return;
    }
   }
  Response response = triggerResponse.getResponseValue();
  if (response != null) {
   Response.RuntimeResponse runtimeResponse = response.manufactureRuntimeResponse();
   m_runtimeResponses.addElement( runtimeResponse );
   m_runtimeResponseArray = null;
   }
  }
 public void trigger () {
  trigger( System.currentTimeMillis()*0.001 );
  }

 //Rem @Override
 // To execute instructions
 // From: edu.cmu.cs.stage3.alice.core.Behavior.schedule(double time)
 // To  : edu.cmu.cs.stage3.alice.core.response.CallToUserDefinedResponse$RuntimeCallToUserDefinedResponse.update(double t): 'm_actual.update(t);'
 protected void internalSchedule (double time, double dt) {
  MultipleRuntimeResponsePolicy mrrp = (MultipleRuntimeResponsePolicy)multipleRuntimeResponsePolicy.getValue();
  Response.RuntimeResponse[] rra = getRuntimeResponseArray();
  //LOB for (RuntimeResponse runtimeResponse : rra)
  RuntimeResponse runtimeResponse = null;
  int t_tam = rra!=null ? rra.length : 0;
  for (int i_i=0; i_i<t_tam; i_i++) {
   runtimeResponse = rra[i_i]; //L
   if (!runtimeResponse.isActive()) { 
    runtimeResponse.prologue( time );
    }

   // edu.cmu.cs.stage3.alice.core.response.CallToUserDefinedResponse$RuntimeCallToUserDefinedResponse.update(time)
   runtimeResponse.update( time ); // to execute instructions________________________________________________________

   double timeRemaining = runtimeResponse.getTimeRemaining( time );
   if (timeRemaining<=0) {
    runtimeResponse.epilogue( time );
    runtimeResponse.HACK_markForRemoval();
   } else {
    if (mrrp != MultipleRuntimeResponsePolicy.INTERLEAVE_MULTIPLE) {
     break;
     }
    }
   } // for (int i_i=0; i_i<t_tam; i_i++)
  if (m_runtimeResponses.size()>0) {
   synchronized (m_runtimeResponses) {
    java.util.Enumeration enu = m_runtimeResponses.elements();
    while (enu.hasMoreElements()) {
     //L Response.RuntimeResponse runtimeResponse = (Response.RuntimeResponse)enu.nextElement();
     runtimeResponse = (Response.RuntimeResponse)enu.nextElement();
     if (runtimeResponse.HACK_isMarkedForRemoval()) {
      m_runtimeResponses.removeElement( runtimeResponse );
      m_runtimeResponseArray = null;
      }
     }
    }
   } // if (m_runtimeResponses.size()>0)
  } // protected void internalSchedule(double time, double dt)

 //Rem @Override
 public void stopAllRuntimeResponses (double time) {
  Response.RuntimeResponse[] rra = getRuntimeResponseArray();
  //LOB for (RuntimeResponse runtimeResponse : rra)
  int t_tam = rra!=null ? rra.length : 0;
  for (int i_i=0; i_i<t_tam; i_i++) {
   rra[i_i].stop( time ); //L runtimeResponse.stop( time )
   }
  m_runtimeResponses.removeAllElements();
  m_runtimeResponseArray = null;
  }

 //Rem @Override
 protected void started (edu.cmu.cs.stage3.alice.core.World world, double time) {
  super.started( world, time );
  m_runtimeResponses.removeAllElements();
  m_runtimeResponseArray = null;
 }
 
 public void setTriggerResponse(ResponseProperty triggerResponse) {
  this.triggerResponse = triggerResponse;
 }

}
